<template>
  <div key="konva-map" class="konva-map col relative-position overflow-hidden">
    <div class="fit map-monitor" @contextmenu="boxContext" @mousemove="boxMousemove"></div>
    <ZoomTool>
      <template v-if="$slots['map-tools']" v-slot:map-tools>
        <slot name="map-tools"></slot>
      </template>
      <div class="text-right relative-position text-caption text-grey-7">
        {{ `${XYCoor.x}, ${XYCoor.y}` }}
      </div>
    </ZoomTool>
    <div class="map-tips absolute text-caption">
      <span class="q-mr-md">{{ modeTips }}</span>
      <span>{{ $t('MapCore.GroundCodeType') }}: {{ openedMap?.mapGroundCode }}</span>
    </div>
    <RightBar :openedMap="openedMap"></RightBar>
    <div v-show="showPointerTips" :style="{left: `${tipPosition.x}px`, top: `${tipPosition.y + 3}px`}" class="absolute">
      <q-tooltip v-model="showPointerTips" :offset="[0, 0]" anchor="bottom left"
                 class="pointer-tips text-body2 bg-grey-7 q-pa-sm rounded-borders text-white" self="top left">
        <div class="text-no-wrap">
          {{ `${$t('MapCore.Coord')}：${tipsPointer.x ?? 0}, ${tipsPointer.y ?? 0}` }}
        </div>
        <div class="text-no-wrap q-pt-xs">{{ `${$t('MapCore.StationCode')}：${tipsPointer.pointCode}` }}</div>
        <div class="text-no-wrap q-pt-xs">{{ `${$t('MapCore.StationName')}：${formatPointName(tipsPointer)}` }}</div>
        <div class="text-no-wrap q-pt-xs">
          {{ `${$t('MapCore.StationType')}：${formatPointType(tipsPointer.pointType)}` }}
        </div>
      </q-tooltip>
    </div>
    <q-resize-observer @resize="resizeCanvas"></q-resize-observer>
    <template v-if="mapMode === 'monitor'">
      <RackPanel :mapGroundCode="openedMap?.mapGroundCode"></RackPanel>
      <AlarmAreaPanel :data="monitorInfo.alarmAreas || []"></AlarmAreaPanel>
      <AGVInfoPanel :data="monitorInfo.chargeList || []"></AGVInfoPanel>
      <AMRPanel></AMRPanel>
    </template>
  </div>
  <AttrsDrawer :openedMap="openedMap" readonly></AttrsDrawer>
</template>

<script setup>
import { i18n } from 'boot/i18n'
import { formatNumber } from 'src/utils/utils'
import AMRPanel from 'src/views/MapCore/Monitoring/Panel/AMRPanel.vue'
import AlarmAreaPanel from 'src/views/MapCore/Monitoring/Panel/AlarmAreaPanel.vue'
import RackPanel from 'src/views/MapCore/Monitoring/Panel/RackPanel.vue'
import AGVInfoPanel from 'src/views/MapCore/Monitoring/Panel/AGVInfoPanel.vue'
import {
  clearSelected, destroyCanvas, initCanvas, loadAlarmAMRs, loadMap, onInitEvent, showPointerTips, tipPosition,
  tipsPointer, updateCanvas
} from 'src/views/MapCore/MapGlobal/utils/KonvaEvent'
import { closeSSE, connectSSE } from 'src/views/MapCore/MapGlobal/utils/Monitor.SSE'
import { packagePoints } from 'src/views/MapCore/MapGlobal/utils/PackagePoints'
import ZoomTool from 'src/views/MapCore/MapGlobal/Tools/ZoomTool.vue'
import RightBar from 'src/views/MapCore/MapGlobal/Tools/RightBar.vue'
import AttrsDrawer from 'src/views/MapCore/MapGlobal/AttrTools/AttrsDrawer.vue'
import { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue'
import {
  calculateCoord, drawHeatMapAreaByCoord, initGroupToolsBar, initZoomCanvas
} from 'src/views/MapCore/MapGlobal/utils/MouseEvent'

const props = defineProps({
  mapMode: String, loading: Boolean, openedMap: Object, mapJSON: String, refreshMap: Boolean, monitorInfo: Object,
  alarmAMRs: Array, source: String
})
const emits = defineEmits(['update:loading', 'update:refreshMap', 'refreshHeatMapAreas'])

let CANVAS = null
const screenSize = ref({}), XYCoor = ref({ x: 0, y: 0 })

const modeTips = computed(() => {
  const { mapMode } = props
  if (mapMode === 'edit') return i18n.t('MapCore.EditMode')
  if (mapMode === 'preview') return i18n.t('MapCore.PreviewMode')
  if (mapMode === 'monitor') return i18n.t('MapCore.MonitorMode')
  return ''
})

watch(() => props.mapMode, mapMode => {
  if (mapMode === 'monitor') connectSSE(CANVAS, props.openedMap.mapGroundCode, props.monitorInfo)
  else closeSSE(CANVAS, props.monitorInfo)
  clearSelected()
})
watch(() => props.refreshMap, val => {
  if (!val) return
  const { mapJSON = '' } = props || {}, { mapGroundCode, isFocusArea } = props.openedMap, mapInfo = JSON.parse(mapJSON)
  mapInfo.isZoom = !isFocusArea
  mapInfo.nonAreaAndText = props.source === 'heatMap'
  loadMap(mapInfo, () => {
    CANVAS && CANVAS.name(mapGroundCode)
    emits('update:loading', true)
  }, () => {
    isFocusArea && focusArea()
    isFocusArea && loadAlarmAMRs(props.alarmAMRs)
    emits('update:loading', false)
    emits('update:refreshMap', false)
    if (props.source === 'heatMap') emits('refreshHeatMapAreas')
  })
  initGroupToolsBar()
})
onMounted(() => {
  CANVAS = initCanvas('map-monitor', (canvas) => {
    if (!canvas) return
    if (screenSize.value.width) canvas.size(screenSize.value)
    initZoomCanvas(canvas)
    onInitEvent()
  })
})
const resizeCanvas = size => {
  screenSize.value = size
  if (!CANVAS) return
  const { width, height } = CANVAS.size()
  if (width !== size.width || height !== size.height) CANVAS && CANVAS.size(size)
}

const boxContext = e => e.preventDefault()
const boxMousemove = e => {
  e.preventDefault()
  XYCoor.value = calculateCoord(CANVAS)
}

const focusArea = () => {
  const { areaCode } = props.openedMap || {}
  if (!CANVAS || !areaCode) return
  const { areaX = 0, areaY = 0, areaWidth = 0, areaHeight = 0 } = props.openedMap || {}
  const minX = Number(areaX), maxY = Number(areaY)
  const maxX = minX + Number(areaWidth), minY = maxY + Number(areaHeight)
  initZoomCanvas(CANVAS, { minX, minY, maxX, maxY }, 'mini')
}
const formatPointName = point => {
  if (!point) return ''
  if (point.pointName) return point.pointName
  const x = formatNumber((point.x || 0) * 1000) + '', y = formatNumber((point.y || 0) * 1000) + ''
  return `${x.padStart(6, '0')}${props.openedMap?.mapGroundCode || ''}${y.padStart(6, '0')}`
}
const formatPointType = code => (packagePoints.value.find(p => p.positionPackageCode === code) ||
  {}).positionPackageName || ''

onBeforeUnmount(() => {
  closeSSE(CANVAS, props.monitorInfo)
  destroyCanvas()
  CANVAS && CANVAS.destroy() && (CANVAS = null)
})

const refreshHeatMapAreas = (heatMapAreas = []) => {
  const { areaGroup, textGroup } = updateCanvas(void 0)
  areaGroup && areaGroup.removeChildren()
  textGroup && textGroup.removeChildren()
  for (const area of heatMapAreas) drawHeatMapAreaByCoord(CANVAS, area)
  emits('update:loading', false)
}
defineExpose({ refreshHeatMapAreas })
</script>